﻿using System;
using UnityEngine;

namespace BToolkit
{
    public class LunPan : MonoBehaviour
    {
        enum State
        {
            /// <summary>
            /// 停止
            /// </summary>
            Stop,
            /// <summary>
            /// 加速
            /// </summary>
            Accelerate,
            /// <summary>
            /// 匀速
            /// </summary>
            ConstantSpeed,
            /// <summary>
            /// 减速
            /// </summary>
            Deceleration
        }
        public RectTransform zhuanpan;
        public AudioClip run, confirm;
        public LunPan_Cell textPoint;
        int cellCount = 16;
        [HideInInspector]
        public LunPan_Cell[] cells;
        State currState = State.Stop;
        float constantSpeedTime = 0.1f, constantSpeedTimer;
        float repeatRate = 0.02f;
        //旋转数据
        [Header("转盘")]
        public float angleOffset = 0;
        public float cellOffset = 0;
        public Sprite[] coinIconLevels = new Sprite[4];
        float zhuanpanAngleStopOffset;
        float accelerate = 0.3f;//加速
        float deceleration = 0.1f;//减速
        int subTimes = 100;//减速次数
        float accelerateAngle, decelerationAngle;
        float accelerateSpeed, decelerationSpeed;
        int stopIndex;
        Action<int> StopEvent;
        float cellAngle;
        float addAngleForSound;

        public void CreateCells(int[] coinValues, string format = null)
        {
            zhuanpan.localEulerAngles = new Vector3(0, 0, -angleOffset);
            textPoint.gameObject.SetActive(false);
            cellCount = coinValues.Length;
            cells = new LunPan_Cell[cellCount];
            cellAngle = 360 / (float)cellCount;
            float angle = -cellOffset;
            for (int i = 0; i < cells.Length; i++)
            {
                LunPan_Cell cell = Instantiate(textPoint);
                cell.transform.SetParent(textPoint.transform.parent, false);
                cell.gameObject.SetActive(true);
                cell.SetContent(this, coinValues[i], format);
                Vector2 pos;
                float radius = textPoint.rectTransform.anchoredPosition.y;
                float radian = angle * Mathf.PI / 180f;
                pos.x = Mathf.Sin(radian) * radius;
                pos.y = Mathf.Cos(radian) * radius;
                angle += cellAngle;
                cell.rectTransform.anchoredPosition = pos;
                cell.rectTransform.localEulerAngles = new Vector3(0, 0, -i * cellAngle + cellOffset);
                cells[i] = cell;
            }
        }

        /// <summary>
        /// 开始转动轮盘 参数：指定停止的角度索引和回调，该索引在轮盘停止时的回调传回
        /// </summary>
        public void StartRotate(int stopIndex, Action<int> OnStop)
        {
            //随机偏移一些角度，以模拟真实性
            float oneItemAngle = 360 / (float)cellCount;
            float offset = UnityEngine.Random.Range(-oneItemAngle * 0.4f, oneItemAngle * 0.4f);
            zhuanpanAngleStopOffset = offset;

            this.stopIndex = stopIndex;
            this.StopEvent = OnStop;
            //加速初始配置
            accelerateSpeed = 0;
            accelerateAngle = zhuanpan.localEulerAngles.z;
            //减速初始配置
            decelerationSpeed = 0;
            decelerationAngle = 360 * stopIndex / (float)cellCount;
            for (int i = 0; i < subTimes; i++)
            {
                decelerationSpeed += deceleration;
                decelerationAngle += decelerationSpeed;
            }
            currState = State.Accelerate;
            InvokeRepeating("RotateUpdate", 0, repeatRate);
        }

        void RotateUpdate()
        {
            switch (currState)
            {
                case State.Accelerate:
                    //加速
                    accelerateSpeed += accelerate;
                    accelerateAngle -= accelerateSpeed;
                    addAngleForSound += accelerateSpeed;
                    if (accelerateSpeed >= decelerationSpeed)
                    {
                        constantSpeedTimer = constantSpeedTime;
                        currState = State.ConstantSpeed;
                    }
                    zhuanpan.localEulerAngles = new Vector3(0, 0, accelerateAngle);
                    break;
                case State.ConstantSpeed:
                    //匀速
                    constantSpeedTimer -= repeatRate;
                    if (constantSpeedTimer <= 0f)
                    {
                        currState = State.Deceleration;
                    }
                    addAngleForSound += accelerateSpeed;
                    zhuanpan.localEulerAngles -= new Vector3(0, 0, accelerateSpeed);
                    break;
                case State.Deceleration:
                    //减速
                    decelerationAngle -= decelerationSpeed;
                    decelerationSpeed -= deceleration;
                    addAngleForSound += decelerationSpeed;
                    if (decelerationSpeed < 0f)
                    {
                        decelerationSpeed = 0;
                        CancelInvoke("RotateUpdate");
                        if (StopEvent != null)
                        {
                            StopEvent(stopIndex);
                        }
                        SoundPlayer.PlayAndDestroy(0, confirm);
                        //dididiPlayer.Play(0, confirm);
                        currState = State.Stop;
                    }
                    zhuanpan.localEulerAngles = new Vector3(0, 0, -angleOffset + decelerationAngle + zhuanpanAngleStopOffset);
                    break;
            }
            if (addAngleForSound >= cellAngle)
            {
                addAngleForSound = 0;
                SoundPlayer.PlayAndDestroy(0, run);
                //dididiPlayer.Play(0, run);
            }
        }

    }
}